iT邦幫忙

2022 iThome 鐵人賽

DAY 6
1
Modern Web

這些那些你可能不知道我不知道的Web技術細節系列 第 6

你可能不知道URL的路徑編碼Percent-encoding

  • 分享至 

  • xImage
  •  

前言

語言文字事件有趣的事情,英文由26個字母反覆組合,描述各種現象。中文永字八筆,構築千萬象形文字。在電腦的世界裡,一切的一切都是由無數個0和1所表示,你所從螢幕見到的任何文字、圖片、影片都是。在文字的表示法中,有一個最早誕生的編碼方式--ASCII Code。從某種角度來說,它也是在電腦世界中最安全的表示方式。

我們介紹過如何安全的儲存JavaScript程式碼而不受到編碼影響。如何在有限的字元中,在網頁HTML表達多國語言的文字。分享過DNS與電腦是如何認識IDN。這次,要來說說URL裡關於Path字段的編碼方式。

URL格式

當我們瀏覽https://bob:bobby@www.lunatech.com:8080/file;p=1?q=2#third[^1],實際上可以將這個URL拆分成好幾個部分來看。

+-------------------+---------------------+
|        Part       |       Data          |
+-------------------+---------------------+
|  Scheme           | https               |
|  User             | bob                 |
|  Password         | bobby               |
|  Host             | www.lunatech.com    |
|  Port             | 8080                |
|  Path             | /file;p=1           |
|  Path parameter   | p=1                 |
|  Query            | q=2                 |
|  Fragment         | third               |
+-------------------+---------------------+

https://bob:bobby@www.lunatech.com:8080/file;p=1?q=2#third
\___/   \_/ \___/ \______________/ \__/\_______/ \_/ \___/
  |      |    |          |          |      | \_/  |    |
Scheme User Password    Host       Port  Path |   | Fragment
        \_____________________________/       | Query
                       |               Path parameter
                   Authority

以網頁瀏覽來說,協議或Scheme通常是HTTP或HTTPS。然後通常缺省的帳號與密碼,因爲以身份驗證來說,現今更常使用其他種方式驗證,比如OpenID。緊接着可能是使用puncode編碼表示的Host和Port。最後是今天要提到的部分 -- Path。

在仔細看Path後的部分,通常是網頁應用框架、SPA(Single Page Application)或是瀏覽器本身會關注的資訊,包含了主要Path、Query和Fragment。其中Query由?開始,通常用x-www-form-urlencoded方式編碼;Fragment由#開始,又被稱爲錨點(Anchor)

百分號編碼Percent-encoding

Domain或稱之爲Host的部分使用puncode編碼,而後續的Path則是使用百分號編碼(Percent-encoding)[^2]。

百分號編碼主要定義了一些保留字,使用保留字的字元,必須先轉換成有百分號(%)開頭,加上數字的表示方式。

保留字

常見的保留字包含#&/:;=??後的表示Query的部分;#後的是Fragment。因此若需要使用到,需要先經過轉義。像是/就需要轉義成%2F;空白通常轉換成%20+轉換成%2B

百分號編碼

通常來說可以使用ASCII表的字,轉換成百分號編碼就是百分號(%)加上以16進位表示的ASCII,或是使用16進位的UTF-8表示的數字。使用編碼過後的結果與使用未保留的字元,有些情況下表示意義相同。比如可以在www-data目錄下再建立一個目錄sub,然後建立index.html

<!-- www-data/sub/index.html -->
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8"/>
    <title>percent-encoding</title>
  </head>
  <body>
    <h1>Hello, World</h1>
  </body>
</html>

然後透過docker啓動nginx:

docker run --name nginx --rm -p 8080:80 -v "${PWD}/www-data":/usr/share/nginx/html nginx

現在除了 http://localhost:8080/sub/index.html
可以瀏覽到該頁面外,還可以透過 
http://localhost:8080/sub%2findex.html
瀏覽,更甚甚至可以透過 http://localhost:8080/sub%2f%69%6e%64%65%78%2e%68%74%6d%6c 瀏覽。

Lab

這次我們在www-data目錄下建立一個?.html檔案

<!-- www-data/?.html -->
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8"/>
    <title>percent-encoding</title>
  </head>
  <body>
    <h1>給我一個大大的?</h1>
  </body>
</html>

然後瀏覽 http://xn--ji8h.127.0.0.1.nip.io:8080/%F0%9F%8D%8C.htmlhttp://xn--ji8h.127.0.0.1.nip.io:8080/%F0%9F%8D%8C.html 看看。

是的我偷渡IDN的概念進來。只可惜我的瀏覽器沒辦法在host部分顯式emoji。

參考資料

[^1]: Stackoverflow-URL encoding the space character: + or %20?。取用時間:2022-09-21。
[^2]: 維基百科-百分號編碼。取用時間:2022-09-21。

可惜在iT邦幫忙有些emoji顯式好像不算正常,會顯式?
不過沒關係你可以到我的網站閱讀看看。
本文同時發表於我的隨筆


上一篇
你可能不知道隱藏在Domain裡的編碼punycode
下一篇
你可能不知道的即時更新方案:Polling
系列文
這些那些你可能不知道我不知道的Web技術細節33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言